import { getSystemInfo } from "."

export const getCanvasContext = (id, width, height) => new Promise((resolve, reject) => {
    const query = wx.createSelectorQuery()
    query.select(id)
    .fields({
        node: true,
        size: true
    })
    .exec((res)=>{
        const { node } = res[0]
        if(node) {
            node.width = width
            node.height = height
            const context = node.getContext('2d')
            resolve(context);
        } else {
            reject()
        }
    })
})


export class CustomCanvas {
    defaultOptions = {
        id: '#canvasPoster',
        width: 500,
        height: 500,
        pixelRatio: 1
    }
    options = {}
    node
    context
    dpr
    sysInfo = {}
    constructor(options) {
        this.options = Object.assign(this.defaultOptions, options)
        
    }
    // ! 初始化Context对象 获取context和node对象
    initContext() {
        return new Promise((resolve, reject) => {
            const query = wx.createSelectorQuery()
            query.select(this.options.id)
            .fields({
                node: true,
                size: true
            })
            .exec((res)=>{
                const { node } = res[0]
                // console.log(node)
                if(node) {
                    this.node = node
                    this.context = node.getContext('2d')
                    resolve();
                } else {
                    reject()
                }
            })
        })
    }
    // ! 处理模糊度
    resizeCanvas() {
        this.dpr = this.sysInfo.pixelRatio
        this.node.width = this.options.width * this.dpr
        this.node.height = this.options.height * this.dpr
        this.context.scale(this.dpr, this.dpr)
    }
    async init() {
        await this.initContext() // todo 初始化node和context
        this.sysInfo = await getSystemInfo() // todo 获取系统信息
        this.resizeCanvas() // todo 处理模糊度
    }
    getNode() {
        if(this.node) { //todo 如果node存在则直接取
            return Promise.resolve(this.node)
        } else { //todo 否则初始化
            return this.init()
            .then(() => {
                return this.node
            })
        }
    }

    getContext() {
        if(this.context) {
            return Promise.resolve(this.context)
        } else {
            return this.init()
            .then(() => {
                return this.context
            })
        }
    }


    drawWaterMarker(url) {
        return new Promise(resolve => {
            const image = this.node.createImage()
            image.src = url
            image.onload = () => {
                for(let w = 0; w < this.options.width + image.width; w+=image.width) {
                    for(let h = 0; h < this.options.height + image.height; h+=image.height) {
                        this.context.drawImage(image, w, h, image.width, image.height)
                    }
                }
                resolve()
            }
        })
    }
    
    /**
     * 
     * @param {String} url 图片路径
     * @param {Number} x canvas上的x轴的起始点
     * @param {Number} y canvas上y轴的起始点
     * @param {Number} width canvas画这张图的宽度
     * @param {Number} height canvas画这张图的高度
     * @param  {...any} args 
     * @returns Promise 绘画结束
     */
    drawImage(url, x, y, width, height, ...args) {
        return new Promise((resolve, reject) => {
            const image = this.node.createImage()
            image.src = url
            image.onload = () => {
            //   console.log(image.width, image.height)
              const ratio = image.width / image.height // todo 获取图片自身的宽高比
              height = Math.ceil(width / ratio) // todo 根据宽度算出如果不失真展示情况下 图片高度
              this.context.drawImage(image, x, y, width, height, ...args)
              resolve({width, height})
            }
            image.onerror = () => {
                reject()
            }

        })
      
    }
    /**
     * @description 根据文字以及要展示长度进行文字渲染
     * @author LiJinFei
     * @param  {String} text 要在画布上输出的文字
     * @param  {Number} x 起点X轴 
     * @param  {Number} y 起点y轴
     * @param  {Number} textWidth 要展示文字的宽度
     * @param  {string} [fontStyle='normal 400 15px  PingFangSC-Regular'] 字体样式
     * @param  {string} [color='#303133'] 字体颜色
     * @return {void}@memberof CustomCanvas
     */
    drawText(text, x, y, textWidth, fontStyle = 'normal 400 15px  PingFangSC-Regular', color = '#303133') {
        this.context.font = fontStyle
        this.context.fillStyle = color
        const texts = this.getTextsByTextWidth(textWidth, text, this.context);
        console.log(texts)
        texts.forEach((text, index) => {
            y = y + (index* 30)
            this.context.fillText(text, x, y)
        })
    }

    /**
     * @description 根据文本框都将文字分成数组
     * @author LiJinFei
     * @param  {Number} lineWidth 宽度
     * @param  {String} text 
     * @param  {CanvasContext} ctx Canvas对象
     * @return Array<String>
     * @memberof CustomCanvas
     */
    getTextsByTextWidth(lineWidth, text, ctx) {
        return text.split('').reduce((prev, next) => {
            if(prev.length > 0) {
                const {width: lastTextWidth} = ctx.measureText(prev[prev.length - 1].join(''))
                const {width: singleTextWidth} = ctx.measureText(next)
                if((lastTextWidth + singleTextWidth) <= lineWidth) {
                    prev[prev.length - 1].push(next)
                } else {
                    prev.push([next])
                }
                
            } else {
                prev.push([next])
            }
            return prev
        }, []).map(item => item.join(""))
    }
}